import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.regex.Pattern;


public class LeitorInstancias {		
	
	/* Campos do arquivo de entrada */
	String p; // Número de facilitadores a serem ativados
	String pontos[][];

	// Nome dos arquivos
	String nomeArqDistancias;
	String nomeArqDemandas;	

	
	/* Campos dos arquivos de saída */
	
	// distancias.txt
	String n; // Número de vértices
	Double matrizDis[][];	
	
	// demandas.txt
	String demandas[];
	
	// tipos.txt
	String tipos[];	
	
	public LeitorInstancias() {
	}	
	
	public void leArqDistancias(String nomeArquivo) {
		try {
			InputStreamReader streamReader = new InputStreamReader(new FileInputStream(nomeArquivo));
			BufferedReader buffReader = new BufferedReader(streamReader);
			
			nomeArqDistancias = nomeArquivo.substring(nomeArquivo.lastIndexOf('/') + 1, nomeArquivo.lastIndexOf('.') );					
			for (int i = 0; i < nomeArqDistancias.length(); i++) {
				if (Character.isDigit(nomeArqDistancias.charAt(i))) 
					nomeArqDistancias = nomeArqDistancias.substring(i, nomeArqDistancias.length());
			}				
			
			String linha = buffReader.readLine();
			this.n = linha.substring(0, linha.indexOf(" ")); 
			pontos = new String[Integer.valueOf(this.n)][2];			
			
			for  (int i = 0; (linha = buffReader.readLine()) != null; i++)				
				pontos[i] = linha.split(" ");	
			
			buffReader.close();
			
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();			
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}		
	}


	public void leArqDistancias2(String nomeArquivo) {
		 try {
			InputStreamReader streamReader = new InputStreamReader(new FileInputStream(nomeArquivo));
                        BufferedReader buffReader = new BufferedReader(streamReader);

                        nomeArqDistancias = nomeArquivo.substring(nomeArquivo.lastIndexOf('/') + 1, nomeArquivo.lastIndexOf('.') );
                        for (int i = 0; i < nomeArqDistancias.length(); i++) {
                                if (Character.isDigit(nomeArqDistancias.charAt(i)))
                                        nomeArqDistancias = nomeArqDistancias.substring(i, nomeArqDistancias.length());
                        }			

			String linha = buffReader.readLine();
                        this.n = linha.substring(0, linha.indexOf(" "));
                        pontos = new String[Integer.valueOf(this.n)][2];
			demandas = new String[Integer.valueOf(this.n)];

			Scanner scanner;

                        for  (int i = 0; (linha = buffReader.readLine()) != null; i++) {  
				scanner	= new Scanner(linha);

                                pontos[i][0] = String.valueOf(new Double(scanner.nextDouble()) ); 
                                pontos[i][1] = String.valueOf(new Double(scanner.nextDouble()) ); 
				scanner.nextInt();
                                demandas[i] = String.valueOf(new Integer(scanner.nextInt()) ); 							
			}


			/*Scanner scanner = new Scanner(new FileInputStream(nomeArquivo));
			this.n = String.valueOf(new Integer(scanner.nextInt()));
                        pontos = new String[Integer.valueOf(this.n)][2];

			System.out.println(scanner.nextInt()); // Ignora o valor de p que consta no arquivo 

			//System.out.println("nextLine: " + scanner.nextLine());
			//System.out.println("nextLine: " + scanner.nextLine());
			int i = 0;
			while (scanner.hasNext()) {
				System.out.println(scanner.nextLine());	
                                pontos[i][0] = String.valueOf(new Double(scanner.nextDouble()) ); 
                                pontos[i][1] = String.valueOf(new Double(scanner.nextDouble()) ); 
				scanner.nextInt();
                                demandas[i++] = String.valueOf(new Integer(scanner.nextInt()) ); 				
			}

			scanner.close();*/


                } catch (FileNotFoundException fnfe) {
                        fnfe.printStackTrace();
                } catch (IOException ioe) {
                        ioe.printStackTrace();
                }
	}
	
	public void leArqDemandas(String nomeArquivo) {	
		try {
			InputStreamReader streamReader = new InputStreamReader(new FileInputStream(nomeArquivo));
			BufferedReader buffReader = new BufferedReader(streamReader);										
			
			nomeArqDemandas = nomeArquivo.substring(nomeArquivo.lastIndexOf('/') + 1, nomeArquivo.lastIndexOf('.') );			
			for (int i = 0; i < nomeArqDemandas.length(); i++) {
				if (Character.isDigit(nomeArqDemandas.charAt(i))) 
					nomeArqDemandas = nomeArqDemandas.substring(i, nomeArqDemandas.length());
			}				
			
			demandas = new String[Integer.valueOf(this.n)];
			tipos = new String[Integer.valueOf(this.n)];
			
			String linha = null;
			for  (int i = 0; (linha = buffReader.readLine()) != null; i++) {
				demandas[i] = linha;
				tipos[i] = "1";
			}																				
			
			buffReader.close();
			
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();			
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}	
	
	public void preparaArquivosSaida(String pasta) {	
		File file = new File(pasta + "arquivos_gerados");
		file.mkdir();
		
		montaMatrizAdjacencia();
		preparaArqDistancia(pasta);
		preparaArqDemandas(pasta);
		//preparaArqTipos(pasta);		
	}
	
	private void montaMatrizAdjacencia() {		
		this.matrizDis = new Double[pontos.length][pontos.length];				
		
		for (int i = 0; i < pontos.length; i++) {
			for (int j = 0; j < pontos.length; j++) {
				matrizDis[i][j] = Math.round(calculaDistEuclidiana(pontos[i], pontos[j]) * 100.0) / 100.0;
			}			
		}			
	}	

	public void preparaArqDistancia(String pasta) {
		try {
			FileOutputStream fos = new FileOutputStream(pasta + "arquivos_gerados/" + nomeArqDistancias + "_distancias.txt");
			PrintWriter writer = new PrintWriter(fos);			
			
			writer.print(this.n);
			writer.println();
			
			for (int i = 0; i < matrizDis.length; i++) {
				for (int j = 0; j < matrizDis[i].length; j++) {									
					writer.print(matrizDis[i][j] + " ");						
				}		
				writer.println();
			}
			
			writer.flush();
			writer.close();
			
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();			
		}
		catch (Exception e) {
			e.printStackTrace();			
		}
	}
	
	public void preparaArqDemandas(String pasta) {
		try {
			FileOutputStream fos = new FileOutputStream(pasta + "arquivos_gerados/" + nomeArqDemandas + "_demandas.txt");			
			PrintWriter writer = new PrintWriter(fos);				
						
			for (int i = 0; i < demandas.length; i++) 
				writer.print(demandas[i] + " ");							
			
			writer.flush();
			writer.close();
			
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();			
		}
	}			

	public void preparaArqTipos(String pasta) {
		try {
			FileOutputStream fos = new FileOutputStream(pasta + "arquivos_gerados/tipos.txt");			
			PrintWriter writer = new PrintWriter(fos);			
						
			for (int i = 0; i < tipos.length; i++) 
				writer.print(tipos[i] + " ");							
			
			writer.flush();
			writer.close();
			
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();			
		}				
	}		
	
	private Double calculaDistEuclidiana(String[] ponto1, String[] ponto2) {		
		double x1 = Double.valueOf(ponto1[0]);
		double y1 = Double.valueOf(ponto1[1]);
		
		double x2 = Double.valueOf(ponto2[0]);
		double y2 = Double.valueOf(ponto2[1]);
		
		double a = Math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );			
		
		return Double.valueOf(a);
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		LeitorInstancias leitor = new LeitorInstancias();	

		leitor.leArqDistancias2(args[0]);
		//leitor.leArqDemandas(args[1]);				
		leitor.preparaArquivosSaida("./");			
	}

}
